#include<stdio.h>
#include "core/default_acs_client.h"
#include "core/profile/i_client_profile.h"
#include "core/regions/end_point_provider.h"
#include "core/http/http_helper.h"
#include "core/http/http_response.h"

namespace aliyun {

DefaultAcsClient::DefaultAcsClient(IClientProfile *i_client_profile)
  : i_client_profile_weak_ptr_(i_client_profile) {
}

bool DefaultAcsClient::GetAcsResponse(AcsRequest *request, AcsResponse *response,
  ISigner *i_signer, const Credential* credential, bool auto_retry, int max_retry_number) {
  if(NULL == request || NULL == response) {
    response->SetCode("SDK.InvalidParameter");
    response->SetMessage("request or response is NULL.");
    return false;
  }
  if(NULL == i_client_profile_weak_ptr_ && (NULL == i_signer || NULL == credential ||
    request->GetRegionId().empty() || request->GetAcceptFormat().empty())) {
    response->SetCode("SDK.InvalidProfile");
    response->SetMessage("No active profile found.");
    return false;
  }
  if(NULL == i_signer) {
    i_signer = i_client_profile_weak_ptr_->GetSigner();
  }
  if(NULL == credential) {
    credential = &(i_client_profile_weak_ptr_->GetCredential());
  }
  if(request->GetRegionId().empty()) {
    request->SetRegionId(i_client_profile_weak_ptr_->GetRegionId());
  }
  if(request->GetAcceptFormat().empty()) {
    request->SetAcceptFormat(i_client_profile_weak_ptr_->GetFormat());
  }
  if(request->GetMethod().empty()) {
    request->SetMethod("GET");
  }
  string domain = EndpointProvider::FindProductDomain(request->GetRegionId(), request->GetProduct());
  if(domain.empty()) {
    response->SetCode("SDK.InvalidRegionId");
    response->SetMessage("Can not find endpoint to access.");
    return false;
  }
  string request_url = request->ComposeUrl(i_signer, credential, domain);
  HttpResponse* http_response = HttpHelper::GetResponse(request_url, request->GetMethod(), NULL, &request->GetHeaders());
  if(NULL == http_response) {
    response->SetCode("SDK.ServerUnreachable");
    response->SetMessage("Speicified endpoint or uri is not valid.");
    return false;
  }
  int retry_times = 1;
  while (500 <= http_response->GetStatus() && auto_retry && retry_times < max_retry_number) {
    request_url = request->ComposeUrl(i_signer, credential, "");
    HttpHelper::ReleaseResponse(http_response);
    http_response = HttpHelper::GetResponse(request_url, request->GetMethod(), NULL, &request->GetHeaders());
    if(NULL == http_response) {
      response->SetCode("SDK.ServerUnreachable");
      response->SetMessage("Speicified endpoint or uri is not valid.");
      return false;
    }
    retry_times ++;
  }
  size_t body_length = 0;
  const unsigned char* body = http_response->GetBody(body_length);
  bool is_success = http_response->IsSuccess();
  response->ParseBody(body, body_length, is_success, request->GetAcceptFormat());
  HttpHelper::ReleaseResponse(http_response);
  return is_success;
}


} // namespace aliyun {

// end of file
